import re
import shutil
from pathlib import Path
from typing import Dict, List, Optional, Tuple
from .detector import detect_distro
from .backup import BackupManager

class MirrorManager:
    def __init__(self, distro_name: str, distro_version: str = ""):
        """
        初始化镜像管理器
        :param distro_name: 发行版名称 (e.g. ubuntu/centos)
        :param distro_version: 发行版版本 (e.g. 22.04/7)
        """
        self.distro = distro_name
        self.version = distro_version or self._detect_version()
        self.mirror_data = self._load_preset_mirrors()
        self.backup_manager = BackupManager(self.distro)

    def _detect_version(self) -> str:
        """补充检测系统版本"""
        _, version = detect_distro()
        return version

    def _load_preset_mirrors(self) -> Dict[str, dict]:
        """加载预设镜像源数据"""
        return {
            "tuna": {
                "name": "清华大学",
                "urls": {
                    "ubuntu": "https://mirrors.tuna.tsinghua.edu.cn/ubuntu/",
                    "centos": "https://mirrors.tuna.tsinghua.edu.cn/centos/",
                    "arch": "https://mirrors.tuna.tsinghua.edu.cn/archlinux/",
                    "gentoo": "https://mirrors.tuna.tsinghua.edu.cn/gentoo",
                    "nixos": "https://mirrors.tuna.tsinghua.edu.cn/nix-channels"

                },
                "template": {
                    "ubuntu": self._ubuntu_template,
                    "centos": self._centos_template
                }
            },
            "aliyun": {
                "name": "阿里云",
                "urls": {
                    "ubuntu": "https://mirrors.aliyun.com/ubuntu/",
                    "centos": "https://mirrors.aliyun.com/centos/",
                    "arch": "https://mirrors.aliyun.com/archlinux/",
                    "gentoo": "https://mirrors.aliyun.com/gentoo",
                    "nixos": "https://mirrors.aliyun.com/nix-channels"
                },
                "template": {
                    "ubuntu": self._ubuntu_template
                }
            },
            "aliyun": {
                "name": "中科大",
                "urls": {
                    "ubuntu": "https://mirrors.ustc.edu.cn/ubuntu/",
                    "centos": "https://mirrors.ustc.edu.cn/centos/",
                    "arch": "https://mirrors.ustc.edu.cn/archlinux/",
                    "gentoo": "https://mirrors.ustc.edu.cn/gentoo",
                    "nixos": "https://mirrors.ustc.edu.cn/nix-channels"
                },
                "template": {
                    "ubuntu": self._ubuntu_template
            }
        }

    def get_available_mirrors(self) -> List[str]:
        """获取当前发行版可用的预设镜像名称"""
        return [
            name for name, data in self.mirror_data.items()
            if self.distro in data["urls"]
        ]

    def validate_mirror_url(self, url: str) -> bool:
        """验证镜像URL有效性"""
        patterns = {
            "ubuntu": r"https?://.*/ubuntu/?",
            "centos": r"https?://.*/centos/?",
            "arch": r"https?://.*/archlinux/?$"
        }
        return re.match(patterns.get(self.distro, ""), url) is not None

    def apply_mirror(self, mirror_name: str, enable_backup: bool = True):
        """
        应用预设镜像配置
        :param mirror_name: 镜像名称 (e.g. tuna/aliyun)
        :param enable_backup: 是否创建备份
        """
        if mirror_name not in self.mirror_data:
            raise ValueError(f"不支持的预设镜像: {mirror_name}")
        
        mirror_info = self.mirror_data[mirror_name]
        template_func = mirror_info["template"].get(self.distro)
        if not template_func:
            raise NotImplementedError(f"该镜像不支持 {self.distro} 发行版")

        config_path = self._get_config_path()
        if enable_backup:
            self.backup_manager.create(config_path)

        config_content = template_func(mirror_info["urls"][self.distro])
        config_path.write_text(config_content)

    def add_custom_mirror(self, name: str, url: str, overwrite: bool = False):
        """添加自定义镜像源"""
        if name in self.mirror_data and not overwrite:
            raise KeyError(f"镜像名称 {name} 已存在，使用 overwrite=True 强制覆盖")
        
        if not self.validate_mirror_url(url):
            raise ValueError(f"无效的镜像URL格式: {url}")
        
        self.mirror_data[name] = {
            "name": "自定义镜像",
            "urls": {self.distro: url},
            "template": {
                self.distro: self._generate_generic_template
            }
        }

    def _get_config_path(self) -> Path:
        """获取当前发行版的配置文件路径"""
        paths = {
            "ubuntu": Path("/etc/apt/sources.list"),
            "centos": Path("/etc/yum.repos.d/CentOS-Base.repo"),
            "arch": Path("/etc/pacman.d/mirrorlist")
        }
        path = paths.get(self.distro)
        if not path or not path.exists():
            raise FileNotFoundError(f"未找到 {self.distro} 的配置文件")
        return path

    # -------------------- 各发行版配置模板生成器 --------------------
    def _ubuntu_template(self, base_url: str) -> str:
        """生成Ubuntu源配置模板"""
        codename = self._get_ubuntu_codename()
        return f"""# 由 mirror-tool 生成
deb {base_url} {codename} main restricted universe multiverse
deb {base_url} {codename}-updates main restricted universe multiverse
deb {base_url} {codename}-backports main restricted universe multiverse
deb {base_url} {codename}-security main restricted universe multiverse
"""

    def _get_ubuntu_codename(self) -> str:
        """获取Ubuntu版本代号 (e.g. jammy)"""
        try:
            return subprocess.check_output(
                ["lsb_release", "-cs"], 
                text=True
            ).strip()
        except subprocess.CalledProcessError:
            return f"ubuntu-{self.version}"

    def _centos_template(self, base_url: str) -> str:
        """生成CentOS基础仓库模板"""
        return f"""# CentOS-Base.repo
[base]
name=CentOS-{self.version} - Base
baseurl={base_url}/$releasever/os/$basearch/
gpgcheck=1
enabled=1

[updates]
name=CentOS-{self.version} - Updates
baseurl={base_url}/$releasever/updates/$basearch/
gpgcheck=1
enabled=1
"""

    def _generate_generic_template(self, base_url: str) -> str:
        """通用模板生成器"""
        return f"""# 由 mirror-tool 生成
# 发行版: {self.distro} {self.version}
{base_url}
"""

# 示例用法
if __name__ == "__main__":
    # Ubuntu 示例
    ubuntu_mgr = MirrorManager("ubuntu", "22.04")
    ubuntu_mgr.apply_mirror("tuna")
    
    # 添加自定义镜像
    ubuntu_mgr.add_custom_mirror("my-mirror", "http://internal-mirror/ubuntu/")
    print(ubuntu_mgr.get_available_mirrors())  # ['tuna', 'aliyun', 'my-mirror']